home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / ADVANCED / texwinalign.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  8.8 KB  |  355 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1998. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. /* This program demonstrates how to use the texture matrix
  9.    and texture coordinate generation (texgen) to generate
  10.    window space texture coordinates for arbitrary 3D geometry.
  11.    The basic technique is to generate texture coordinates
  12.    directly matching the object coordinates and using the
  13.    texture matrix to mimic the viewport, projection, and
  14.    modelview transformations to convert the texture coordinates
  15.    into window coordinates identically to how the actual
  16.    object coordinates are transformed into window space.  It
  17.    is important to have perspective correct texturing if you
  18.    want perspective projections to look right. */
  19.  
  20. #include <stdlib.h>
  21. #include <GL/glut.h>
  22.  
  23. GLfloat lightDiffuse[] = {1.0, 0.0, 0.0, 1.0};  /* Red diffuse light. */
  24. GLfloat lightPosition[] = {1.0, 1.0, 1.0, 0.0};  /* Infinite light location. */
  25.  
  26. GLfloat n[6][3] = {  /* Normals for the 6 faces of a cube. */
  27.   {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
  28.   {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} };
  29. GLint faces[6][4] = {  /* Vertex indices for the 6 faces of a cube. */
  30.   {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
  31.   {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} };
  32. GLfloat v[8][3];  /* Will be filled in with X,Y,Z vertexes. */
  33.  
  34. GLfloat angle = -20.0;
  35. int animating = 1;
  36.  
  37. #define TEX_WIDTH 16
  38. #define TEX_HEIGHT 16
  39.  
  40. /* Nice circle texture tiling pattern. */
  41. static char *circles[] = {
  42.   "....xxxx........",
  43.   "..xxxxxxxx......",
  44.   ".xxxxxxxxxx.....",
  45.   ".xxx....xxx.....",
  46.   "xxx......xxx....",
  47.   "xxx......xxx....",
  48.   "xxx......xxx....",
  49.   "xxx......xxx....",
  50.   ".xxx....xxx.....",
  51.   ".xxxxxxxxxx.....",
  52.   "..xxxxxxxx......",
  53.   "....xxxx........",
  54.   "................",
  55.   "................",
  56.   "................",
  57.   "................",
  58. };
  59.  
  60. /* Nice grid texture tiling pattern. */
  61. static char *grid[] = {
  62.   "..............xx",
  63.   "..............xx",
  64.   "..............xx",
  65.   "..............xx",
  66.   "..............xx",
  67.   "..............xx",
  68.   "..............xx",
  69.   "..............xx",
  70.   "..............xx",
  71.   "..............xx",
  72.   "..............xx",
  73.   "..............xx",
  74.   "..............xx",
  75.   "..............xx",
  76.   "xxxxxxxxxxxxxxxx",
  77.   "xxxxxxxxxxxxxxxx",
  78. };
  79.  
  80. static void
  81. makeTexture(char *pattern[])
  82. {
  83.   GLubyte floorTexture[TEX_WIDTH][TEX_HEIGHT][3];
  84.   GLubyte *loc;
  85.   int s, t;
  86.  
  87.   /* Setup RGB image for the texture. */
  88.   loc = (GLubyte*) floorTexture;
  89.   for (t = 0; t < TEX_HEIGHT; t++) {
  90.     for (s = 0; s < TEX_WIDTH; s++) {
  91.       if (pattern[t][s] == 'x') {
  92.     /* Nice green. */
  93.         loc[0] = 0x6f;
  94.         loc[1] = 0x8f;
  95.         loc[2] = 0x1f;
  96.       } else {
  97.     /* Light gray. */
  98.         loc[0] = 0xaa;
  99.         loc[1] = 0xaa;
  100.         loc[2] = 0xaa;
  101.       }
  102.       loc += 3;
  103.     }
  104.   }
  105.  
  106.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  107.  
  108.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  109.   glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_WIDTH, TEX_HEIGHT, 0,
  110.     GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
  111. }
  112.  
  113. void
  114. drawBox(void)
  115. {
  116.   int i;
  117.  
  118.   for (i = 0; i < 6; i++) {
  119.     glBegin(GL_QUADS);
  120.     glNormal3fv(&n[i][0]);
  121.     glVertex3fv(&v[faces[i][0]][0]);
  122.     glVertex3fv(&v[faces[i][1]][0]);
  123.     glVertex3fv(&v[faces[i][2]][0]);
  124.     glVertex3fv(&v[faces[i][3]][0]);
  125.     glEnd();
  126.   }
  127. }
  128.  
  129. void
  130. display(void)
  131. {
  132.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  133.   glPushMatrix();
  134.     glRotatef(angle, 0.0, 0.0, 1.0);
  135.     drawBox();
  136.   glPopMatrix();
  137.   glutSwapBuffers();
  138. }
  139.  
  140. int windowWidth;
  141. int windowHeight;
  142. int slideX = 0, slideY = 0;
  143.  
  144. void
  145. configTextureMatrix(void)
  146. {
  147.   glMatrixMode(GL_TEXTURE);
  148.   glLoadIdentity();
  149.   /* Shift texture in pixel units (slideX,slideY).  You could use this
  150.      to copensate for a viewport origin different from the window
  151.      origin. */
  152.   glTranslatef(slideX/(GLfloat)TEX_WIDTH,
  153.                slideY/(GLfloat)TEX_HEIGHT,
  154.            0.0);
  155.   /* Scale based on the window size in pixel. */
  156.   glScalef(windowWidth/(GLfloat)TEX_WIDTH,
  157.            windowHeight/(GLfloat)TEX_HEIGHT,
  158.        1.0);
  159.   /* Mimic the scene's projection matrix setup. */
  160.   gluPerspective( /* field of view in degree */ 40.0,
  161.     /* aspect ratio */ 1.0,
  162.     /* Z near */ 1.0, /* Z far */ 10.0);
  163.   /* Mimic the scene's view matrix setup. */
  164.   gluLookAt(0.0, 0.0, 5.0,  /* eye is at (0,0,5) */
  165.     0.0, 0.0, 0.0,      /* center is at (0,0,0) */
  166.     0.0, 1.0, 0.);      /* up is in positive Y direction */
  167.   /* Mimic the scene's model matrix setup. */
  168.   /* Adjust cube position to be aesthetic angle. */
  169.   glTranslatef(0.0, 0.0, -1.0);
  170.   glRotatef(60, 1.0, 0.0, 0.0);
  171.   glRotatef(angle, 0.0, 0.0, 1.0);
  172.   /* Switch back to the modelview matrix. */
  173.   glMatrixMode(GL_MODELVIEW);
  174.  
  175. }
  176.  
  177. void
  178. idle(void)
  179. {
  180.   /* Slowly rotate object. */
  181.   angle += 0.5;
  182.   if (angle > 360.0) {
  183.     angle -= 360.0;
  184.   }
  185.   /* Make sure the texture matrix mimics the changing
  186.      modelview matrix. */
  187.   configTextureMatrix();
  188.   glutPostRedisplay();
  189. }
  190.  
  191. void
  192. keyboard(unsigned char c, int x, int y)
  193. {
  194.   switch(c) {
  195.   case 27: /* Escape */
  196.     exit(0);
  197.     break;
  198.   case 'h':
  199.     slideX--;
  200.     break;
  201.   case 'j':
  202.     slideY--;
  203.     break;
  204.   case 'k':
  205.     slideY++;
  206.     break;
  207.   case 'l':
  208.     slideX++;
  209.     break;
  210.   case 'r':
  211.     angle += 10;
  212.     break;
  213.   case 'a':
  214.     animating = !animating;
  215.     if (animating) {
  216.       glutIdleFunc(idle);
  217.     } else {
  218.       glutIdleFunc(NULL);
  219.     }
  220.     break;
  221.   }
  222.   configTextureMatrix();
  223.   glutPostRedisplay();
  224. }
  225.  
  226. void
  227. reshape(int width, int height)
  228. {
  229.   windowWidth = width;
  230.   windowHeight = height;
  231.   glViewport(0, 0, width, height);
  232.   configTextureMatrix();
  233. }
  234.  
  235. void
  236. init(void)
  237. {
  238.   static GLfloat sPlane[4] = { 1.0, 0.0, 0.0, 0.0 };
  239.   static GLfloat tPlane[4] = { 0.0, 1.0, 0.0, 0.0 };
  240.   static GLfloat rPlane[4] = { 0.0, 0.0, 1.0, 0.0 };
  241.   static GLfloat qPlane[4] = { 0.0, 0.0, 0.0, 1.0 };
  242.  
  243.   /* Setup cube vertex data. */
  244.   v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
  245.   v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
  246.   v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
  247.   v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
  248.   v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
  249.   v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
  250.  
  251.   /* Use depth buffering for hidden surface elimination. */
  252.   glEnable(GL_DEPTH_TEST);
  253.  
  254.   /* Enable a single OpenGL light. */
  255.   glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
  256.   glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
  257.   glEnable(GL_LIGHT0);
  258.  
  259.   /* Setup the view of the cube. */
  260.   glMatrixMode(GL_PROJECTION);
  261.   gluPerspective( /* field of view in degree */ 40.0,
  262.     /* aspect ratio */ 1.0,
  263.     /* Z near */ 1.0, /* Z far */ 10.0);
  264.   glMatrixMode(GL_MODELVIEW);
  265.   gluLookAt(0.0, 0.0, 5.0,  /* eye is at (0,0,5) */
  266.     0.0, 0.0, 0.0,      /* center is at (0,0,0) */
  267.     0.0, 1.0, 0.);      /* up is in positive Y direction */
  268.  
  269.   /* Texgen that maps object coordinates directly to texture
  270.      coordinates. */
  271.   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  272.   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  273.   glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  274.   glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  275.   glTexGenfv(GL_S, GL_OBJECT_PLANE, sPlane);
  276.   glTexGenfv(GL_T, GL_OBJECT_PLANE, tPlane);
  277.   glTexGenfv(GL_R, GL_OBJECT_PLANE, rPlane);
  278.   glTexGenfv(GL_Q, GL_OBJECT_PLANE, qPlane);
  279.   glEnable(GL_TEXTURE_GEN_S);
  280.   glEnable(GL_TEXTURE_GEN_T);
  281.   glEnable(GL_TEXTURE_GEN_R);
  282.   glEnable(GL_TEXTURE_GEN_Q);
  283.  
  284.   /* Enable texturing.  Perspective correct texturing is
  285.      important to this demo! */
  286.   glEnable(GL_TEXTURE_2D);
  287.   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  288.  
  289.   /* Adjust cube position to be aesthetic orientation. */
  290.   glTranslatef(0.0, 0.0, -1.0);
  291.   glRotatef(60, 1.0, 0.0, 0.0);
  292. }
  293.  
  294. void
  295. menu(int selection)
  296. {
  297.   switch (selection) {
  298.   case 1:
  299.     glEnable(GL_LIGHTING);
  300.     glutPostRedisplay();
  301.     break;
  302.   case 2:
  303.     glDisable(GL_LIGHTING);
  304.     glutPostRedisplay();
  305.     break;
  306.   case 3:
  307.     keyboard('a', 0, 0);
  308.     break;
  309.   case 4:
  310.     makeTexture(circles);
  311.     break;
  312.   case 5:
  313.     makeTexture(grid);
  314.     break;
  315.   case 666:
  316.     exit(0);
  317.   }
  318. }
  319.  
  320. void
  321. visibility(int state)
  322. {
  323.   if (state == GLUT_VISIBLE) {
  324.     if (animating) {
  325.       glutIdleFunc(idle);
  326.     }
  327.   } else {
  328.     glutIdleFunc(NULL);
  329.   }
  330. }
  331.  
  332. int
  333. main(int argc, char **argv)
  334. {
  335.   glutInit(&argc, argv);
  336.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  337.   glutCreateWindow("window space aligned textures");
  338.   glutDisplayFunc(display);
  339.   glutReshapeFunc(reshape);
  340.   glutKeyboardFunc(keyboard);
  341.   glutVisibilityFunc(visibility);
  342.   init();
  343.   makeTexture(grid);
  344.   glutCreateMenu(menu);
  345.   glutAddMenuEntry("Enable lighting", 1);
  346.   glutAddMenuEntry("Disable lighting", 2);
  347.   glutAddMenuEntry("Animating", 3);
  348.   glutAddMenuEntry("Circles", 4);
  349.   glutAddMenuEntry("Grid", 5);
  350.   glutAddMenuEntry("Quit", 666);
  351.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  352.   glutMainLoop();
  353.   return 0;             /* ANSI C requires main to return int. */
  354. }
  355.